iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
自我挑戰組

新手也想開始認識機器學習系列 第 25

Day 25 遞迴神經網路 RNN 、梯度下降與梯度消失

  • 分享至 

  • xImage
  •  

介紹

遞迴神經網路 RNN (recurrent neural networks)是神經網路的一種,它是一種循環的網路,最常被用來處理時間和序列相關的問題。簡單的架構如圖所示:

在上面的示例圖中,我們能夠看到神經網路區塊 A 在讀取輸入 https://chart.googleapis.com/chart?cht=tx&chl=%24x_t%24 後,將會輸出一個值 https://chart.googleapis.com/chart?cht=tx&chl=%24h_t%24。而每次讀取過的值都會有部份傳遞至下一次讀取時的區塊 A 裡。而 RNN 便是透過這樣子的循環,來將資訊從上一步傳遞至下一步。

經過上面的介紹後我們就不難理解為何 RNN 常常備用來處理時間和序列相關的問題了,因為下一個的輸出能夠考慮上一個的資訊嘛!這就像是我們吃完早餐後才會吃中餐;吃完中餐後才會吃晚餐一樣,RNN 是能夠考慮"序列"的先後關係的。

然而 RNN 有相當嚴重的問題,叫作 梯度消失梯度爆炸,這個我們晚點再提。

昨天我們有說過,為了得知預測結果究竟與實際答案差了多少,於是科學家設計了代價函數,並希望代價函數愈小愈好,對吧?那我們該如何快速求出最小的代價函數呢?答案是梯度下降法。

梯度下降法 (Gradient Descent)

梯度下降是一種能夠快速找出最小代價函數的方法。高中數學有教過,我們可以利用微分的技術來求函數的最大值與最小值。因此當我們的變數是線性關係時,我們就能夠用梯度下降法來快速的求出代價函數 J 的最小值,如圖:

目前主流的方法便是隨機選擇一个斜率為初始值,然後在每次迭代時使用一個樣本對參數進行更新(mini-batch size =1),我們稱呼這種方法為隨機梯度下降法(Stochastic Gradient Descent)。

但是,現實的變數往往不會那麼剛好呈線性關係。因此當我們在做梯度下降時,很容易找到局部最小值而非全域最小值,如圖:

當然遇到這種情況也有解法,例如批量梯度下降(Batch Gradient Descent),但是每迭代一步,都要用到訓練集所有的資料。當然還有其他方法,例如牛頓法、momentum 或是 Adam 。

總之,如何找到最低最小的最佳解一直都是科學家們想要嘗試解決的目標,在實際應用時通常會根據問題的使用情境而有所不同,這時我們就需要透過不同的方式來解決,例如限制迭代次數或是設置學習率等,只要找到屬於自己最佳的優化方式就可以了!

梯度消失與梯度爆炸

下圖是一張簡單的深度網路模型:

首先,我們假設每一層網路激活後的輸出為https://chart.googleapis.com/chart?cht=tx&chl=%24%5Cdisplaystyle%20f_%7Bi%7D(x)%24 ,i 為第 i 層,x 代表第 i 層的輸入,https://chart.googleapis.com/chart?cht=tx&chl=%24%5Cdisplaystyle%20f%24 為激活函數,我們便能得出:
本層輸出=https://chart.googleapis.com/chart?cht=tx&chl=%24f%24(上層輸出 * 本層權重 + 偏置)
https://chart.googleapis.com/chart?cht=tx&chl=%24f_%7Bi%2B1%7D%3Df(f_%7Bi%7D%20%20w_%7Bi%2B1%7D%2Bb_%7Bi%2B1%7D)%24

簡寫為:https://chart.googleapis.com/chart?cht=tx&chl=%24f_%7Bi%2B1%7D%3Df(f_%7Bi%7D%20w_%7Bi%2B1%7D)%24

以此類推的話,假設今天我們的隱藏層超級簡單只有三層,那我們從輸入層經過隱藏層到輸出層的前向傳播公式為:
https://chart.googleapis.com/chart?cht=tx&chl=%24f(w_1)%3Df(w_3f_2(w_2f_1(w_1)))%24

現在我們對 https://chart.googleapis.com/chart?cht=tx&chl=%24w_1%24 求梯度,根據連鎖律,我們可以推倒出
https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cdisplaystyle%20%7B%5Cpartial%20f%20%5Cover%20%5Cpartial%20w_1%7D%3D%7B%5Cpartial%20f3%20%5Cover%20%5Cpartial%20f2%7D%7Bw_3%7D%7B%5Cpartial%20f_2%20%5Cover%20%5Cpartial%20f_1%7D%7Bw_2%7D%7B%5Cpartial%20f_1%20%5Cover%20w_1%7D%7D%24

可以看出,https://chart.googleapis.com/chart?cht=tx&chl=%24w_1%24 求梯度就是反向從輸出層到輸入層的用連鎖律求導

而假如我們使用標準化初始 https://chart.googleapis.com/chart?cht=tx&chl=%24w%24,那麼各個層次的相乘都是0-1之間的小數,而激活函數 https://chart.googleapis.com/chart?cht=tx&chl=%24f%24 的導數也是 0~1 之間的數(例如 sigmoid 激活函數),那麼在神經網絡反向傳播中,當梯度由後往前傳時,其連乘後結果會變的很小,最後變為零。此時,淺層的神經網絡權重得不到更新,而隨著隱藏層數目的增加,分類準確率反而下降了。這種稱呼這種情況為梯度消失

若我們初始化的 https://chart.googleapis.com/chart?cht=tx&chl=%24w%24 是很大的數,https://chart.googleapis.com/chart?cht=tx&chl=%24w%24 大到乘以激活函數的導數都大於 1 ,那麼連乘後,可能會導致求導的結果很大,使得學習不穩定,參數變化太大導致無法獲取最優參數。這種稱呼這種情況為梯度爆炸

因此,梯度消失問題和梯度爆炸問題一般會隨著神經網絡層數的增加變得越來越明顯。現在我們回頭看 RNN 就不難發現它的問題:
只要輸入的資料太長,RNN 就容易記不住前面的資料導致梯度消失;而過長的資料導致在調整權重時可能一個不小心就會引發梯度爆炸。然而我們使用神經網路的目的,不就是希望能夠讓電腦學習更多資料,好讓電腦預測的精準度超過使用演算法的機器學習嗎?該怎麼樣才能在輸入大量資料讓神經網路進行學習時不引發梯度消失和梯度爆炸?

另外,RNN 的設計結構其實相當仰賴前面所學的資訊,可是只要輸入的資料一長,隨著權重更新 RNN 可能就會忘記前面學到的資訊了!(我們稱呼這種問題為"長期依賴(Long-Term Dependencies)")

明天就讓我們來講講改良後的 RNN 結構:長短期記憶網路 LSTM 吧!


上一篇
Day 24 深度學習與人工神經網路
下一篇
Day 26 長短期記憶網路 LSTM
系列文
新手也想開始認識機器學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言